package com.li.onjava8.concurrent.cf.exception;

import com.li.onjava8.concurrent.cf.task.Breakable;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

/**
 * 与CompletableFuture在处理链中包装对象的方式相同，它还可以缓冲异常。
 * 这些不会在处理过程中显示给调用者，而只会在你尝试提取结果时显示。
 * @author li
 * @date 2023/11/1 9:50
 */
public class CompletableExceptions {
    static CompletableFuture<Breakable> test(String id, int failcount) {
        return CompletableFuture.completedFuture(new Breakable(id, failcount))
                .thenApply(Breakable::work)
                .thenApply(Breakable::work)
                .thenApply(Breakable::work)
                .thenApply(Breakable::work);
    }

    public static void main(String[] args) {
        test("A", 1); //异常
        test("B", 2); //异常
        test("C", 3); //异常
        test("D", 4); //异常
        test("E", 5);
        try {
            test("F", 2).get(); //异常警告
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException(e);
        }

        System.out.println(test("G", 2).isCompletedExceptionally()); //异常
        //测试H告诉我们，无论异常成功与否，异常仍然可以被视为“完成”
        System.out.println(test("H", 2).isDone());                   //异常
        CompletableFuture<Integer> cfi = new CompletableFuture<>();
        System.out.println("done? " + cfi.isDone());
        //如何在CompletableFuture中插入异常，而不管是否存在任何故障
        cfi.completeExceptionally(new RuntimeException("forced"));
        try {
            cfi.get();      //异常警告
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException(e);
        }
    }
}
